﻿using System.Windows;
using System.Windows.Threading;

namespace Xioa_UI.Domain;

/// <summary>
/// 防抖工具类
/// </summary>
public static class Debouncer
{
    private static System.Timers.Timer? _timerDbc;
    private static System.Timers.Timer? _timerTrt;
    private static object _dbcObj = new object();
    private static object _trtObj = new object();

    /// <summary>
    /// 延迟指定毫秒后执行
    /// 在此期间如果再次调用，则重新计时
    /// </summary>
    /// <param name="dispatcherObject">ui线程对象</param>
    /// <param name="action"></param>
    /// <param name="timeMs"></param>
    public static void Debounce(this Dispatcher dispatcherObject, Action action, int timeMs = 500)
    {
        lock (_dbcObj)
        {
            _timerDbc?.Dispose();
            _timerDbc = new System.Timers.Timer(timeMs);
            _timerDbc.AutoReset = false;
            _timerDbc.Elapsed += (o, e) =>
            {
                _timerDbc.Stop();
                _timerDbc.Close();
                _timerDbc = null;
                dispatcherObject.Invoke(action);
            };
            _timerDbc.Start();
        }
    }


    /// <summary>
    /// 即刻执行，执行之后，在指定毫秒内再次调用无效
    /// </summary>
    /// <param name="action"></param>
    /// <param name="timeMs">不应期，这段时间内调用无效</param>
    /// <param name="dispatcher">ui线程对象</param>
    public static void Throttle(this Dispatcher dispatcher, Action action, int timeMs = 2000)
    {
        lock (_trtObj)
        {
            if (_timerTrt != null) return;
            _timerTrt = new System.Timers.Timer(timeMs);
            _timerTrt.AutoReset = false;
            _timerTrt.Elapsed += (o, e) =>
            {
                _timerTrt.Stop();
                _timerTrt.Close();
                _timerTrt = null;
            };
            _timerTrt.Start();
            dispatcher.Invoke(action);
        }
    }
}